/*================================================================
*   Copyright (C) 2021 IMVS Ltd. All rights reserved.
*   
*   Filename   ：main.c
*   Creator    ：Chase Wu
*   Create Date：2021/04/07
*   Description：
*
================================================================*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>

#include "cantool.h"
#include "serial.h"

enum TESTTOOL_TYPE{
	TESTTOOL_TYPE_NONE,
    TESTTOOL_TYPE_CAN,
    TESTTOOL_TYPE_UART,
	TESTTOOL_TYPE_NET,
};

enum TRANS_MODE{
    RECV_MODE,
    SEND_MODE,
	LOOPBACK_MODE,
};

static void print_usage(char *app)
{
	fprintf(stdout, "Usage:  %s <-r -s> <interface name> \n", app);
	fprintf(stdout, "        -r, --receive     Receive data test mode \n");
	fprintf(stdout, "        -s, --send        Send data test mode \n");
	fprintf(stdout, "        -l, --loopback    Send data test mode loopback\n");
	fprintf(stdout, "        -h, --help        Display this help \n");
	fprintf(stdout, "        -v, --version     Display this version \n");
	fprintf(stdout, "\n");
}

static void print_version(void)
{
	printf("Build GCC Version: %s \n", __VERSION__);
	printf("Build Date： %s \n", __DATE__);
	printf("Build Time %s \n", __TIME__);
	printf("\n");
}

static int test_dev_info(char *param)
{
	if(strstr(param, "can")){
		printf("Test Interface: %s\n\n", param);
		return TESTTOOL_TYPE_CAN;
	}else if(strstr(param, "tty")){
		printf("Test Interface: %s\n\n", param);
		return TESTTOOL_TYPE_UART;
	}else if(strstr(param, "eth")){
		printf("Test Interface: %s\n\n", param);
		return TESTTOOL_TYPE_NET;
	}else{
		printf("Test Interface: NULL\n\n");
		return TESTTOOL_TYPE_NONE;
	}
}

static int interface_test(char *param, int mode)
{
	int ret = 0;
	int dev;

	dev = test_dev_info(param);
	if(!dev){
		return -1;
	}

	switch(dev){
		case TESTTOOL_TYPE_CAN:{
			printf("CAN send data test.\n");
			cantool_process(param, mode);
		}break;
		case TESTTOOL_TYPE_UART:{
			printf("UART send data test.\n");
			serial_process(param, mode);

		}break;
		case TESTTOOL_TYPE_NET:{

		}break;
		default:{
			ret = -1;
		}break;
	}

	return ret;
}

static struct option longOpts[] = {
	{ "canid", required_argument, NULL, 'c' },
	{ "send", required_argument, NULL, 's' },
	{ "receive", required_argument, NULL, 'r' },
	{ "loop", required_argument, NULL, 'l' },
	{ "help", no_argument, NULL, 'h' },
	{ "version", no_argument, NULL, 'v' },
	{ 0, 0, 0, 0 }
};

int main(int argc, char* argv[])
{
    int cmd;
	int opt_index = 0;
	// int interface = TESTTOOL_TYPE_UART;

    printf("\n\n");
    printf("------------Interface Test Tools--------------\n\n");

	if(argc < 2){
		print_usage(argv[0]); 
	}
	
    while ((cmd = getopt_long(argc, argv, "h:l:r:s:t:", longOpts, &opt_index)) != -1) {
        switch (cmd) {
		case 0:{
			printf("option %s set canid %s", longOpts[opt_index].name, optarg);
		}break;
		case 'h':{
			print_usage(argv[0]);
		}break;
		case 'l':{
			if(interface_test(optarg, LOOPBACK_MODE) < 0){
				print_usage(argv[0]);
			}
		}break;
		case 'r':{
			if(interface_test(optarg, RECV_MODE) < 0){
				print_usage(argv[0]);
			}
		}break;
		case 's':{
			if(interface_test(optarg, SEND_MODE) < 0){
				print_usage(argv[0]);
			}
		}break;
		case 't':{
			// interface = test_interface_type(optarg);
		}break;
		case 'v':{
			print_version();
		}break;
		case '?':{
			printf("Unknown option: %c\n",(char)optopt);
			print_usage(argv[0]); 
		}break;
		}
    }
	printf("\n");

	return 0;
}